package com.pactera.jep.service.sys.apilog;

import com.pactera.jep.core.code.LogType;
import com.pactera.jep.core.code.OperateType;
import com.pactera.jep.core.context.Context;
import com.pactera.jep.core.entity.Identity;
import com.pactera.jep.core.entity.Log;
import com.pactera.jep.core.holder.SpringContextHolder;
import com.pactera.jep.core.service.LogService;
import com.pactera.jep.core.utils.IPUtils;
import com.pactera.jep.service.sys.util.LogExecutor;
import io.swagger.annotations.ApiOperation;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

@Component
@Aspect
public class ApiLogAspect {
    @Resource
    private LogService logService;

    @Pointcut("@annotation(io.swagger.annotations.ApiOperation)")
    public void logPointCut() {

    }

    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        //执行方法
        Object result = point.proceed();
        //执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;

        //保存日志
        LogExecutor.submit(()->{
            saveSysLog(point, time, result);
        });

        return result;
    }

    private void saveSysLog(ProceedingJoinPoint point, long time, Object result) {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();

        Log dto = new Log();
        getOperate(method, dto);
        ApiOperation syslog = method.getAnnotation(ApiOperation.class);
        String content = syslog.value();
        //注解上的描述,操作日志内容
        dto.setLogType(LogType.OPERATE.getValue());
        dto.setOperateDesc(content);
        //请求的方法名
        String className = point.getTarget().getClass().getName();
        String methodName = signature.getName();
        dto.setUrl(className + "." + methodName + "()");
        HttpServletRequest request = SpringContextHolder.getHttpServletRequest();
        String ip = IPUtils.getRealIP(request);
//        String mac = IPUtils.getMacByIp(ip);
        //设置IP地址
        dto.setIp(ip);
//        dto.setMacAddress(mac);
        //获取登录用户信息
        Identity sysUser = Context.getIdentityContext() == null ? null : Context.getIdentityContext().getIdentity();
        if (sysUser != null) {
            dto.setStaffCode(sysUser.getId());
            dto.setStaffName(sysUser.getName());
        }
        //耗时
        dto.setCostTime(String.valueOf(time));
        dto.setCreateTime(new Date());
        //保存系统日志
        logService.addLog(dto);
    }

    private void getOperate(Method method, Log dto) {
        if (method.getName().contains("query") || method.getName().contains("get")
                || method.getName().contains("list")
        ) {
            dto.setOperateType(OperateType.QUERY.getValue());
        }
        if (method.getName().contains("save")) {
            dto.setOperateType(OperateType.ADD.getValue());
        }
        if (method.getName().contains("save") || method.getName().contains("add")) {
            dto.setOperateType(OperateType.ADD.getValue());
        }
        if (method.getName().contains("remove") || method.getName().contains("delete")) {
            dto.setOperateType(OperateType.DELETE.getValue());
        }
        if (method.getName().contains("edit") || method.getName().contains("update")) {
            dto.setOperateType(OperateType.UPDATE.getValue());
        }
        if (method.getName().contains("mark")) {
            dto.setOperateType(OperateType.UPDATE.getValue());
        }
    }

}
